<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>函数重载</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="xfunc-sql.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="extend.html">快退</a></td><td width="60%" align="center" valign="bottom">章33. 扩展 SQL</td><td width="10%" align="right" valign="top"><a href="extend.html">快进</a></td><td width="10%" align="right" valign="top"><a href="xfunc-volatility.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="XFUNC-OVERLOAD">33.5. 函数重载</a></h1><a name="AEN36465"></a>
<p>多个函数可以定义成同样的 SQL 名字，只要它们接受的参数不同。换句话说，函数名可以<i class="FIRSTTERM">重载</i>。在执行一个查询的时候，服务器会从提供的参数类型和个数上判断应该调用哪个函数。重载也可以用于模拟数目不定(有上限)的参数。</p>
<p>在创建一族重载函数的时候，我们应该小心避免歧义。比如，对于下面的函数</p>
<pre class="PROGRAMLISTING">CREATE FUNCTION test(int, real) RETURNS ...
CREATE FUNCTION test(smallint, double precision) RETURNS ...</pre>
<p>如果给出一些简单的输入，比如 <tt class="LITERAL">test(1, 1.5)</tt> ，系统要想判断应该调用哪个函数可不是一件很容易的事情。目前实现的解析规则在<a href="typeconv.html">章10</a>里描述，但是设计一个隐含依赖这些行为的系统是不明智的。</p>
<p>一个接受单个复合类型参数的函数通常不应该和该类型或该类型的任何属性(字段)同名。<tt class="LITERAL">attribute(table)</tt> 被认为等效于 <tt class="LITERAL">table.attribute</tt> 。在这种情况下，一个复合类型上的函数会和一个复合类型的属性有歧义(总是使用属性)。我们可以通过使用模式来修饰函数名(也就是 <tt class="LITERAL">schema.func(table)</tt>)以绕开这个限制，但最好还是通过使用无冲突的名字来避免这个问题。</p>
<p>在重载 C 语言函数的时候，还有一个额外的限制：重载族的每个函数的 C 名字必须和所有其它函数的 C 名字不同，其它函数包括内部的和动态加载的。如果违反这条规则，那么行为是不可移植的。你可能会得到一个运行时的链接错误，或者是其中一个函数被调用(通常是内部的那个)。<tt class="COMMAND">CREATE FUNCTION</tt> 命令可选的 <tt class="LITERAL">AS</tt> 子句把 SQL 函数名和 C 源代码中的函数名分离开。比如，</p>
<pre class="PROGRAMLISTING">CREATE FUNCTION test(int) RETURNS int
    AS '<tt class="REPLACEABLE"><i>filename</i></tt>', 'test_1arg'
    LANGUAGE C;
CREATE FUNCTION test(int, int) RETURNS int
    AS '<tt class="REPLACEABLE"><i>filename</i></tt>', 'test_2arg'
    LANGUAGE C;</pre>
<p>这里的 C 函数名代表许多可能的惯例之一。</p>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="xfunc-sql.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="xfunc-volatility.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">查询语言(SQL)函数</td><td width="34%" align="center" valign="top"><a href="extend.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">函数易失性范畴</td></tr>
</table>
</div>
</body></html>